package cn.addr.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import cn.addr.message.model.UserMessage;
import cn.addr.user.dao.LinkPersonDao;
import cn.addr.user.dao.TagDao;
import cn.addr.user.dao.UserDao;
import cn.addr.user.model.LinkPerson;
import cn.addr.user.model.Tag;
import cn.addr.user.model.UserBean;
import cn.addr.user.service.LinkPersonCRUD;


public class ObjectServer extends Thread {

	private Socket client;
	private static UserDao userDao = UserDao.getInstance();
	private static LinkPersonDao linkPersonDao = LinkPersonDao.getInstance();
	private static TagDao		 tagDao  	   = TagDao.getInstance();
	private static LinkPersonCRUD personCRUD = new LinkPersonCRUD();
	
	public ObjectServer(Socket socket) {
		client = socket;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public void run() {
		ObjectInputStream ois = null;
		ObjectOutputStream oos = null;
		try {
			ois = new ObjectInputStream(client.getInputStream());
			oos = new ObjectOutputStream(client.getOutputStream());
			UserMessage um = (UserMessage) ois.readObject();
			String username = um.getUser().getUsername();
			String password = um.getUser().getPassword();
			if (um.getMessageType() == UserMessage.REGISTER) {
				UserBean user = userDao.register(username, password);
				System.out.println(username+":"+password);
				if(user!=null){
					oos.writeBytes("register success");
					System.out.println("register success");
				}
				else{
					oos.writeBytes("this username was already regitsered");
					System.out.println("this username was already regitsered");
				}
			} else if (um.getMessageType() == UserMessage.XMLMESSAGE) {
				UserBean user = userDao.login(username, password);
				if(user==null){
					System.out.println("login failed");
					oos.writeObject(new Byte((byte) 2));
					return;
				}
				Collection<LinkPerson> linkPersons = um.getLinkPersons();
				Collection<Tag> tags = um.getTags();
				try {
					for(Iterator it = tags.iterator() ; it.hasNext() ; ){
						Tag tag = (Tag) it.next();
						tag.setUser(user);
						for(Iterator it1 = tag.getPersons().iterator() ; it1.hasNext() ; ){
							LinkPerson lp = (LinkPerson) it1.next();
							lp.setUser(user);
						}
					}
					personCRUD.deleteAllUser(user);
					
					linkPersonDao.begin();
					for(Iterator it = linkPersons.iterator() ; it.hasNext() ; ){
						LinkPerson lp = (LinkPerson) it.next();
						lp.setUser(user);
						lp.setId(null);
//						System.out.println(lp.getTag());
						if(lp.getTag()==null)
							linkPersonDao.save(lp);
					}
					linkPersonDao.commit();
					
					tagDao.begin();
					for(Iterator it = tags.iterator() ; it.hasNext() ; ){
						Tag tag = (Tag) it.next();
						tagDao.save(tag);
					}
					tagDao.commit();
					oos.writeObject(new Byte((byte) 7));
					System.out.println("push success");
				} catch (Exception e) {
					oos.writeBytes("push failed");
					System.out.println("push failed");
					e.printStackTrace();
				}finally{
					linkPersonDao.close();
				}
			}else if(um.getMessageType()==UserMessage.RESQUEST){
				UserBean user = userDao.login(username, password);
				if(user==null){
					System.out.println("login failed");
					oos.writeObject(new Byte((byte) 2));
					return;
				}
				DetachedCriteria dc = DetachedCriteria.forClass(LinkPerson.class);
				DetachedCriteria dct = DetachedCriteria.forClass(Tag.class);
				dc.add(Restrictions.eq("user.id", user.getId()));
				dct.add(Restrictions.eq("user.id", user.getId()));
				
				Collection <LinkPerson> retlink = new LinkedHashSet<LinkPerson>();
				Collection<Tag> rettag = new LinkedHashSet<Tag>();
				UserMessage umresp = new UserMessage();
				linkPersonDao.begin();
				List lps = linkPersonDao.search(dc);
				for(Iterator it = lps.iterator() ; it.hasNext() ; ){
					LinkPerson lp = (LinkPerson) it.next();
					System.out.println(lp);
					retlink.add(lp);
				}
				umresp.setLinkPersons(retlink);
				linkPersonDao.commit();
				linkPersonDao.close();
				tagDao.begin();
				List tags = tagDao.search(dct);
				for(Iterator it = tags.iterator() ; it.hasNext() ; ){
					Tag tag = (Tag) it.next();
					System.out.println(tag);
					rettag.add(tag);
				}
				umresp.setTags(rettag);
				tagDao.commit();
				tagDao.close();
				umresp.setMessageType(UserMessage.RESPONSE);
				oos.writeObject(umresp);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}finally{
			if(ois!=null)
				try {
					ois.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			
		}

	}

}
